//Added by Tyler on May 6th

#include "Graphics.h"

FunctionReturn Graphics::Initialize(HWND hWnd)
{
	m_hWnd = hWnd;
	GetWindowRect(hWnd, &m_rClientRect);
	

	if(InitDevice() != SUCCEED)
	return FAIL;

	//Sprite Creation
	D3DXCreateSprite( m_pD3DDevice, &m_pSpriteDevice);

	if(InitTextures() != SUCCEED)
	return FAIL;

	return SUCCEED;

}

FunctionReturn Graphics::InitDevice()
{
	/* Create D3D object */
	m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);

	// Check device capabilities
	DWORD dwBehavior = 0;
	D3DCAPS9 D3DCaps;		// Device Capabilities
	m_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &D3DCaps);

	// Determine vertex processing mode
	if(D3DCaps.DevCaps & D3DCREATE_HARDWARE_VERTEXPROCESSING)
	{
		// Hardware vertex processing supported? (Video Card)
		dwBehavior |= D3DCREATE_HARDWARE_VERTEXPROCESSING;	
	}
	else
	{
		// If not, use software (CPU)
		dwBehavior |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; 
	}
	
	// If hardware vertex processing is on, check pure device support
	if(D3DCaps.DevCaps & D3DDEVCAPS_PUREDEVICE && dwBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING)
	{
		dwBehavior |= D3DCREATE_PUREDEVICE;	
	}

	/* Get default display mode */
	D3DDISPLAYMODE DisplayMode;
	m_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &DisplayMode);

	/* Use display mode to check formats */
	m_pD3D->CheckDeviceFormat(D3DADAPTER_DEFAULT,
							   D3DDEVTYPE_HAL,
							   DisplayMode.Format,
							   D3DUSAGE_DEPTHSTENCIL,
							   D3DRTYPE_SURFACE,
							   D3DFMT_D16);

	/* Check device capabilities against requirements */
	DWORD dwBehaviorFlags = 0;

	/* All system checks passed: create the D3D device */
	D3DPRESENT_PARAMETERS PresentParams;
	memset(&PresentParams, 0, sizeof(PresentParams));
	PresentParams.SwapEffect				= D3DSWAPEFFECT_DISCARD;
	PresentParams.hDeviceWindow				= m_hWnd;
	PresentParams.BackBufferFormat			= DisplayMode.Format;
	PresentParams.Windowed					= TRUE;
	PresentParams.PresentationInterval		= D3DPRESENT_INTERVAL_ONE;  //max fps 60 _ONE OR PRESENT_INTERVAL_IMMEDIATE to unlock fps
	PresentParams.BackBufferWidth			= m_rClientRect.right -m_rClientRect.left;
	PresentParams.BackBufferHeight			= m_rClientRect.bottom - m_rClientRect.top;
	PresentParams.EnableAutoDepthStencil	= TRUE;
	PresentParams.AutoDepthStencilFormat	= D3DFMT_D16;

	m_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
						  D3DDEVTYPE_HAL,
						  m_hWnd,
						  D3DCREATE_HARDWARE_VERTEXPROCESSING,
						  &PresentParams,
						  &m_pD3DDevice);

	D3DXCreateFont(m_pD3DDevice, 30, 0, FW_BOLD, 0, false, DEFAULT_CHARSET,
				   OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Segoe Print"),
				   &m_pFont);

	m_textarray[START].m_String = "Start";
	m_textarray[QUIT].m_String = "Quit";
	m_textarray[IRON].m_String = "Iron:\n0";
	m_textarray[SULFUR].m_String = "Sulfur:\n0";
	m_textarray[GEM].m_String = "Gem:\n0";
	m_textarray[FORFIET].m_String = "Forfeit";
	m_textarray[UPDATE_TEXT].m_String = "Game Info:\nHOWDY";
	SetRect(&m_textarray[6].m_rect, 50, 200, 250, 450);

	for(int i = 0; i < 7; i++)
	{
		m_textarray[i].ifDraw = false;
		
	}

	//Use to set what text says
	//sprintf_s(m_aString, sizeof(m_aString), "Lives:");

	return SUCCEED;
}

FunctionReturn Graphics::InitTextures()
{
	//Have to do this for each nonanimated texture


	TextureInfo* tempTexture;// = new TextureInfo();

	const char* stringarray[] =
	{

		"Resources/Bauxite.jpg",
		"Resources/Calcite.jpg",
		"Resources/Feldspar.jpg",
		"Resources/Pyrite.jpg",
		"Resources/quartz.jpg",
		"Resources/schist.jpg",
		"Resources/Halite.jpg",
		"Resources/Main Menu.png", //Needs to made special
		"Resources/rock.jpg",
		"Resources/Pressed button.png",
		"Resources/Unpressed button.png",
		"Resources/Character.png",
		"Resources/Character2.png",
		"Resources/Geyser Start.jpg",
		"Resources/Geyser Middle.jpg",
		"Resources/Geyser End.jpg",
		"Resources/Track Start.jpg",
		"Resources/Track Mid.jpg",
		"Resources/Track End.jpg",
		"Resources/Card_Placeholder.png"

	};

	for each (const char* filename in stringarray)
	{
		tempTexture = new TextureInfo();
		D3DXCreateTextureFromFile(m_pD3DDevice, filename, &m_pTexture);
		m_pTexture->GetLevelDesc(0, &m_texDesc);
		m_vtexCenter = D3DXVECTOR3(m_texDesc.Width / 2.0f, m_texDesc.Height / 2.0f, 0.0f);
		tempTexture->pTexture = m_pTexture;
		tempTexture->texDesc = m_texDesc;
		tempTexture->vtexCenter = m_vtexCenter;

		m_TxList.add(tempTexture);
	}

	return SUCCEED;
}

FunctionReturn Graphics::Draw(const DrawList* DrList)
{
	/* Clear the back buffer and the z-buffer */
	m_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, BLUE, 1.0f, 0);

	/*
	** Begin the scene:
	**		start rendering everything to the back buffer
	*/
	m_pD3DDevice->BeginScene();

	m_pSpriteDevice->Begin(D3DXSPRITE_ALPHABLEND);

	if(Render2DObjects(DrList) != SUCCEED)
	return FAIL;

	if(RenderFont() != SUCCEED)
	return FAIL;


	m_pSpriteDevice->End();

	m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
	/*
	** End the scene:
	**		drawing is all done
	*/
	m_pD3DDevice->EndScene();
	/*
	** Display the back buffer on the screen
	*/
	m_pD3DDevice->Present(NULL, NULL, NULL, NULL);

	return SUCCEED;

}

#include "Player.h"

FunctionReturn Graphics::Render2DObjects(const DrawList* DrList)
{
	

	//However we want to make the object list
	for (int i = 0; i < DrList->getSize(); i++)
		{
			D3DXMatrixIdentity(&m_matWorld);
			D3DXMatrixIdentity(&m_matTrans);
			D3DXMatrixIdentity(&m_matScale);
			D3DXMatrixIdentity(&m_matRotation);

			//                                                   X                  Y
			D3DXMatrixTranslation(&m_matTrans, DrList->get(i)->m_vPosition.x, DrList->get(i)->m_vPosition.y, 0.0f);
			D3DXMatrixScaling(&m_matScale, 1.0f, 1.0f, 0.0f);
			D3DXMatrixRotationYawPitchRoll(&m_matRotation, DrList->get(i)->m_stRotation.yaw,DrList->get(i)->m_stRotation.pitch,DrList->get(i)->m_stRotation.roll); //Rotation function
			D3DXMatrixMultiply(&m_matWorld, &m_matWorld, &m_matRotation);
			D3DXMatrixMultiply(&m_matWorld, &m_matWorld, &m_matScale);
			D3DXMatrixMultiply(&m_matWorld, &m_matWorld, &m_matTrans);
			m_pSpriteDevice->SetTransform(&m_matWorld);


			//This checks animation, if the object doesn't have a RECT value, it will read false in CheckR()
			/*if (pObj->CheckR() == false)
			{*/
			/*Player* N; N = new Player(PLAYER_ONE);
			N = (Player*)DrList->get(1);*/

			m_pSpriteDevice->Draw(m_TxList.get(DrList->get(i)->textureIndex)->pTexture, NULL, &m_TxList.get(DrList->get(i)->textureIndex)->vtexCenter, NULL, 0xFFFFFFFF);
			/*}
			else
			{
				pObj->Draw();
				m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
				m_pSpriteDevice->Draw(pObj->GetTex(), &pObj->GetR(), &pObj->GetCenter(), NULL, 0xFFFFFFFF);
			}*/

		}

	return SUCCEED;
}

FunctionReturn Graphics::RenderFont()
{
	//LPCSTR m_aString = "WEEEE!";
	// Text on the screen
	//string tempString;

	for each (TextInfo text in m_textarray)
	{
		//tempString = text.m_String.str();

		if(text.ifDraw == true)
		{
			::D3DXMatrixIdentity(&m_matWorld);
			m_pSpriteDevice->SetTransform(&m_matWorld);
			//                                                                   FLAGS TO POSITION TEXT
			m_pFont->DrawText(m_pSpriteDevice, text.m_String.c_str(), -1, &text.m_rect, DT_CENTER | DT_NOCLIP, D3DCOLOR_RGBA(255, 255, 255, 255));
		}
	}
	
	return SUCCEED;
}

FunctionReturn Graphics::RenderDebugTools()
{
	return SUCCEED;
}